package com.gzsxy.utils;

import org.apache.commons.io.IOUtils;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * @author xiaolong
 * @version 1.0
 * @description: 将jar内的文件复制到jar包外的同级目录下
 * @date 2021/9/29 10:14
 */
public class FileCopyUtils {

    /**
     * @param location classpath: 文件路径
     * @return InputStream   输入流
     * @description: 获取jar包内文件的输入流
     */
    private static InputStream getResource(String location) throws IOException {
        //加载资源文件的方法  Classpath:  获取的是target下的文件
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        InputStream in = resolver.getResource(location).getInputStream();
        //将输入流转为byte字节数组
        byte[] bytes = IOUtils.toByteArray(in);
        in.close();
        //这里不直接将inputstream直接返回的原因是，我们需要先关闭输入流就必须先把数据存入byte字节数组中
        return new ByteArrayInputStream(bytes);
    }


    /**
     * @param
     * @return jar包同级的目录
     * @description: 获取项目所在文件夹的绝对路径
     */
    private static String getCurrentDirPath() {
        //如果直接执行.class文件那么会得到当前class的绝对路径。
        //C:/Users/Lenovo/IdeaProjects/demo1/target/classes/
        //如果封装在jar包里面执行jar包那么会得到当前jar包的绝对路径。
        // file:/C:/Users/Lenovo/IdeaProjects/demo1/target/demo1-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/
        URL url = FileCopyUtils.class.getProtectionDomain().getCodeSource().getLocation();
        String path = url.getPath();


        System.out.println(path);
        //检测某请求字符串是否以指定的前缀开始的。
        if (path.startsWith("file:")) {
            path = path.replace("file:", "");
        }
        //判断路径中是否存在.jar!/
        if (path.contains(".jar!/")) {
            path = path.substring(0, path.indexOf(".jar!/") + 4);
        }
        File file = new File(path);
        //获取当前路径的父目录的绝对路径（jar包 同级的目录 target目录）
        path = file.getParentFile().getAbsolutePath();
        return path;
    }


    /**
     * @param
     * @return
     * @description: 返回jar包目录下新的文件路径path
     */
    private static Path getDistFile(String path, boolean ignoreDir) throws IOException {
        //jar包 同级的目录
        String currentDirPath = getCurrentDirPath();
        Path dist = null;
        if (ignoreDir && path.contains("/")) {
            //获取文件名
            path = path.substring(path.lastIndexOf("/"));
        }
        //获取path路径
        dist = Paths.get(currentDirPath + File.separator + path);
        //获取获取当前路径的父路径
        Path parent = dist.getParent();
        if (parent != null) {
            //创建文件
            Files.createDirectories(parent);
        }
        return dist;
    }


    /**
     * @param location  相对路径文件，例如static/test.conf
     * @param ignoreDir 是否忽略文件父目录
     * @return
     * @description: 复制classpath下的文件到jar包的同级目录下
     */
    public static String copy(String location, boolean ignoreDir) throws IOException {
        InputStream in = getResource("classpath:" + location);
        Path dist = getDistFile(location, ignoreDir);
        //文件的复制，输入流，新的文件路径path
        Files.copy(in, dist, StandardCopyOption.REPLACE_EXISTING);
        in.close();
        return dist.toAbsolutePath().toString();
    }

}
